OpenAI Codex 负责人:不懂底层,拿什么管AI

OpenAI Codex 开源仓库技术负责人、前 Meta 杰出工程师迈克尔·博林做客 Developing Dev 播客,12500 字完整访谈,阅读约 27 分钟。

摘要:从 Google Calendar 到 Facebook 构建系统 Buck,从 Nuclide IDE 到虚拟文件系统,再到 OpenAI Codex——博林在每一站都做了同一件事:把让自己痛苦的工具推倒重来。如今他 80-90% 的代码由 AI 生成,但他说,不懂底层的人连问题都问不对。这对 AI 时代的工程师意味着什么?

核心金句

我可以做很多事情,但只有一小部分是我真正喜欢且能取得成功的。如果我坚持做那些我真正喜欢的事情,我会成功得多。

我之所以能解决一些别人解决不了的问题,就是因为我发现两个层级之间存在冗余,如果能去掉它,就能获得 10 倍的性能提升。

第一步:找出你真正喜欢做的事。第二步:找出对雇主来说真正不可或缺的事。第三步:找到两者的交集,然后全力投入。

读这篇你会得到:一位顶级工程师如何在所有人反对时从零构建工具并证明自己;晋升 E9 过程中因沟通方式被延迟的真实教训;AI 时代为什么底层技术功底反而更重要。


本期播客嘉宾是迈克尔·博林(Michael Bolin),OpenAI Codex 开源仓库的技术负责人,前 Meta 杰出工程师(E9)。我们聊了他的职业路径、OpenAI 工程师如何使用 Codex,以及研究导向型与工程导向型公司文化的差异。


Chickenfoot

博林:

天哪,这事儿居然还挺相关的,因为它是我硕士论文的项目。那是一个 Firefox 扩展程序,大概是极少数用 JavaScript 为 Firefox 编写的论文项目之一。它实际上是 Firefox 侧边栏里的一个小编码工具,就像一个小型 REPL(交互式解释器)。它的理念是“面向终端用户的 Web 编程”。

当时有一些函数,比如“输入(enter)”和“点击(click)”之类的。你会输入“enter”,然后传入字符串参数,它就会找到对应的输入框,接着你可以说“点击搜索”或者其他指令。大部分工作都在于我们底层构建的各种启发式算法:如果你说“输入名字”,它会寻找“名字”这个词,找到最近的文本框,然后通过 JavaScript 将其作为输入。

我现在回想起来觉得特别有意思。我们当时做了很多工作,这和现在这些 AI agent(智能体)所做的事情非常相似,只不过现在是真的用自然语言,而不是用这种小型的 JavaScript 替代品。

瑞安:

哦,很有趣。所以它能解析前端,并且有一个 REPL,你可以对它下指令,比如“找到名字输入框”。

博林:

在 Google 工作

瑞安:

你刚入行时非常渴望去 Google,特别是想做 Google Calendar。是什么吸引了你,那里的工作体验如何?

博林:

我是在 90 年代开始上网的。我记得当时浏览网页,你得试用五种不同的搜索引擎,才有可能找到你想找的东西。很有意思的是,我清楚地记得 2000 年 3 月我室友说:“嘿,有个搜索引擎看起来好用多了。”当时它好像还是 Stanford Google Edu 的域名。

我当时就觉得:“哦,这个确实更好。”后来你开始阅读他们的东西,他们确实与众不同。当时的 Yahoo 页面非常杂乱,而 Google 试图保持极简,我觉得他们在当时更有原则。后来,你开始看到身边的人去那里工作,你会想:“天哪,他们招的都是顶尖人才,我想和这些人一起工作。”我觉得他们真正理解 Web,特别是在那个微软甚至砍掉了 Internet Explorer 项目的时候。当时我觉得:“这是通往 Web 的门户,而你们竟然在拆除它。”相比之下,Google 对 Web 的态度要前瞻得多。所以,加上他们的工程质量和影响力,那绝对是我毕业后非常向往的地方。

瑞安:

那时的文化是怎样的?比如你在一些文章里提到过“产品与基础设施”的对比。

博林:

很多公司,尤其是发展到那种规模的公司,创始人往往会对他们起家时擅长的东西情有独钟。信息检索和基础设施显然是推动公司发展的关键。而我当时被吸引过去是因为他们推出了像 Gmail 这样的产品,虽然当时还很模糊,但在公司内部并没有像搜索那样拥有同样的地位。所以,当我做 Calendar 时,它主要还是面向消费者的,虽然也卖给企业,但我们并不是赚钱的主力,在那时可能更像是一个成本中心。

瑞安:

我看到你最终离开了 Google,从你的文章看,那过程似乎挺苦涩的。是什么让你决定离开?

博林:

我在那里待了四年。现实地说,投资回报是一个因素,四年期满后财务状况确实发生了变化。但更重要的是,当时我养成了一个坏习惯:在那些对我个人很重要、但对 Google 来说可能并不重要的项目上投入太多精力。比如我做 Calendar,那还挺重要的;后来我做 Google Tasks,那是 Calendar 里的一个小功能,用户量大概少了两个到三个数量级,但我对它充满热情。我还对 JavaScript 基础设施以及 Closure(Google 的 JavaScript 工具套件)充满热情。我甚至因为太有动力,还去写了关于 Closure 的书。但从职业生涯角度看,这可能不是最好的选择。你会觉得:“我在做高质量的工作,但看着别人得到认可,而我却在拼命干活。”这是一种“只顾埋头苦干,不懂聪明工作”的错误。所以,我觉得我应该去别的地方,或者尝试点别的,看看我所热衷的事情是否也是公司所重视的。

重构 Facebook 的构建系统

瑞安:

后来你回到大厂,加入了 Facebook。我知道你当时是 JavaScript 专家,但你在 Meta 的第一个大项目却是 Android 代码库的构建工具。我想知道你是怎么参与到那个项目里的?

博林:

事情进展得太痛苦了,我心想:“我必须修复这个构建系统。”我知道我用 Java 做过很多事,构建流程不应该慢到这种程度。Facebook 有黑客马拉松文化,所以我决定:“好吧,在黑客马拉松上,我一定要做一个新的构建系统。”我打算以 Google 构建系统的风格,做一个新的工具。当时还有一个叫 FB Build 的系统,是 Google 构建系统的另一个镜像,用 Python 写的,只支持 C 语言。我当时想,要么我把它搞定,要么我就不知道自己能不能在这里待下去,因为每天处理这些东西简直让我抓狂。

瑞安:

如果没修好,你就会辞职吗?

博林:

或者至少会换个项目。我需要找到一个能让我每天开心工作的地方。我来这里是为了写代码、做贡献,我想尽我所能做到最好。有趣的是,我得给那些人点个赞,当时几乎所有人——除了一个人——都告诉我我在做一件非常糟糕的事情。我当时只是个高级 Android 工程师。在 Google,人们可能会说“不”,但在 Facebook,没人直接阻止我。所以我坚持做了下去。相对较快地,我就做出了一个效果好得多、速度快了两倍左右的工具。这让很多人刮目相看,他们说:“好吧,看来我们还是用这个吧。”

瑞安:

我觉得很有趣的是,当时所有困难都堆在一起。很多工程师如果发现同样的问题,可能因为已经有现成的工具,就不会选择重新开始。而且 Google 还有竞争产品,你可能赢不了。是什么让你确信你的项目能胜出并成为默认工具?

博林:

我想有几点原因。第一,就像我说的,我做过其他 Java 项目,我知道它不该这么慢。作为一名软件工程师,从根本上讲,它不应该慢到这种程度。其实大部分阻力来自这种观点:“如果我们偏离了标准,那我们就不是主流了。万一标准工具下周变得快了 100 倍,而我们被困在你的工具上怎么办?”当你想到他们后来甚至自己搞了 PHP 虚拟机和语言时,这真的很有趣。他们多次拥抱“做自己的东西”,为什么这次不同,我不知道。我想当时大家对移动端充满了恐惧,加上工期紧迫。他们觉得:“我们有个高级工程师,听起来他要去搞个科学实验,但我们有硬性截止日期,这是最好的时间利用方式吗?”但最终它成功了。还有一点,我当时尽量表现得低调。我说:“嘿,我只是想做一个 Android 构建系统,我不是要接管公司,也不是要改变别人的项目。”因为我知道那样会招致更多摩擦。我以一种能支持更多公司业务的方式去构建它,但我从不强推。所以一年左右后,当 iOS 团队说“嘿,我们的构建系统太烂了,能用 Buck 吗?”时,我感到非常欣慰。我说:“当然可以,来吧。”

瑞安:

这也很有趣,因为你刚来不久,没什么信誉度。你试图构建东西,所有人都在说“别这么做”,然后你还得说服他们这是正确的方向。在没有信誉的情况下,你是如何影响这种改变的?

博林:

我借用了一些信誉。有一位高级 Android 工程师,也是前 Google 员工,叫约翰·佩洛(John Perlow)。他当时说:“你会成功的,快点做,赶在别人阻止你之前。”他是最早支持我的人之一,而且他是一位非常高产的程序员,所以他真心希望能有更快的开发周期。他是最早给我点赞的人之一,我觉得这很有帮助。但我必须承认,我刚去的时候也犯了一些大错。你提到我没有信誉,我当时从 Google 过来,心想:“哦,这里有贝尔实验室出来的人,有这么多大牛。”然后到了 Facebook,发现:“哦,这群大学生懂什么?”有几次我确实犯了“在 Google 我们是这么做的”这种错误,人们会说:“我们根本不在乎。”在大多数情况下,他们是对的。仅仅因为它在 Google 有效,并不意味着它在 Facebook 也有效。

瑞安:

关于这个话题的最后一个问题,你构建的东西在性能上比其他任何东西都快得多。背后的技术直觉是什么?是什么让它变得如此高效?

博林:

我觉得最重要的一点是,我坐下来研究了 Google 的那个工具,问自己:“它到底在做什么?”我觉得关键在于,Google 的那个工具在任何东西改变时,都会从头开始。这就是为什么它那么慢,特别是在增量构建时。于是我开始真正理解依赖关系。因为 Android 资源处理非常复杂,它是定制的,我想这就是为什么默认情况下大家倾向于把一切推倒重来。但我深入进去后发现:“哦,我们可以利用这一点,如果这些东西没变,我们就可以缓存这一步的结果,不需要重做。”这一下子让速度快了很多。此外,我还支持了“拥有超过四个模块”的想法。当时每次有人增加一个模块,都得写 200 行没人看得懂的 XML ANT 构建脚本。所以没人想模块化,因为没人想承担那个责任。Buck 的一大贡献就是让增加新模块变得简单得多。这意味着我们最终有了更多模块,构建也因此更加增量化。所以,这真的是一种思维方式的转变。

瑞安:

基本上就是减少了冗余工作。

博林:

是的。

重写 Facebook 的 IDE

瑞安:

在解决了 Android 构建问题后,我看到你开始更多地投入到 IDE(集成开发环境)的工作中。你在 IDE 中发现了什么问题,让你想要介入?

博林:

在 Buck 之后,我在 Messenger iOS 团队待了一小段时间。我想:“好吧,我做过 Android 了,也许该扩展一下。”虽然我不喜欢 iOS 开发,而且现在依然不喜欢。人们甚至没意识到 Objective-C 里有一件事存在了很久,叫自动引用计数(ARC)。现在编译器会自动注入,但以前你必须手动添加代码来处理每个引用计数。大多数人没见过那种代码,但通过收购进来的 iOS Messenger 代码太老了,还是用那种旧方式写的。那简直痛苦不堪。我想如果用现在的 Codex,可能早就清理干净了。但当时我们只能忍受。Xcode 对我来说感觉不对劲,我不喜欢头文件和实现文件分离,现在也不喜欢。而且对于 Android 和 iOS,Facebook 总是拥有最大的应用,我们把所有功能都塞进一个应用里并发布,而 Google 有 Drive 应用、Sheets 应用等等,而且他们拥有平台,可以预装 20 个应用。这意味着 Facebook 总是比其他人更早触及移动开发工具的扩展性极限,这很痛苦。但作为开发工具人员,这很有趣,因为我们有机会解决前人未曾解决的问题,而且这不仅仅是科学实验,而是具有真正的商业价值。Xcode 也是如此,我们和苹果沟通过,说:“Xcode 无法支撑我们的项目规模。”他们回答:“你们的项目太大了,应该拆小点。”这就是我们得到的反馈。所以,去构建一个编辑器似乎是合理的。我当时想:“IDE 到底在做什么?它在和 Clang、语言服务器通信。”我想:“我们可以在那之上构建一个更好的外壳。”当时我们已经开始放弃 Git,转而使用 Mercurial。我想:“没人会开箱即用地支持 Mercurial,所以这必须由我们来做。”而且如果 Buck 要成为我们的构建系统,Xcode 永远不会支持这些 Facebook 特有的东西。所以投入时间去改善那种体验是合理的。我当时对 Android 没有这种感觉,因为 IntelliJ 已经相当不错了,我们已经找到了在大规模下使用它的方法。但 Xcode 在当时确实更困难一些。

瑞安:

所以 Xcode 很烂,不符合需求。当时还有另一个团队在构建另一个 IDE,我记得是基于 Web 的?

博林:

是的,是基于 Web 的。我不是在嘲笑它,那部分没问题。但它是基于一个被遗弃的 Google 开源项目构建的,用的是 GWT(Google Web Toolkit),即你写 Java,它会生成 JavaScript。我尝试在他们的基础上构建,甚至还加速了他们的构建过程。但同样,看看迭代时间,而且我发现这是一个被遗弃的开源项目,用的是 GWT。我想:“我们可是 React 公司,为什么不赋能那些想要构建开发工具的人,让他们使用我们所引领的、并且真正喜欢的技术呢?”所以我说:“你们疯了吧。”于是我开始了。这和 Buck 的情况类似,我当时说:“我只是要做一个 Java 构建工具,不是要做万能构建工具。”我当时只是想去旁边搞另一个编辑器,只专注于 iOS,我不是要接管一切。

瑞安:

你不想引火烧身。但那个团队拥有所有现有的用户,对吧?

博林:

他们有成千上万的工程师,可能有一千个。

瑞安:

我想最终领导层选择了后来成为 Nuclide 的项目,也就是你构建的那个。在你没有用户的情况下,为什么他们选择了你?

博林:

瑞安:

我注意到,这个项目加上你的其他工作,最终促成了你晋升到 E8,也就是行业里常说的首席工程师(Principal Engineer)。当时你的反应是什么?

博林:

我当然非常兴奋。我觉得这不仅是对我技术的认可,也是一种验证,证明我不只是在技术上成长,还理解了如何做那些与雇主目标一致的事情。这同样有价值,也同样令人满足。

瑞安:

我知道 Nuclide 是开源的,如果我没记错的话,Buck 也是。开源的理由是什么?

博林:

Buck 的情况更有趣。Nuclide 在外部并没有真正被采用。我觉得在这些情况下,所有这些公司都从开源中受益匪浅。如果它不是什么核心机密,那就分享给别人吧。就像 Codex 以及我职业生涯中的许多其他事情一样。我确实觉得分享信息是好事,即使没人用你的工具。仅仅作为一种参考,看看事情可以怎么做,就已经很棒了。在更好的情况下,你还能得到有意义的贡献。我记得 Uber 采用了 Buck,Airbnb 也用了。就像我说的,Facebook 是最大的应用,所以我们总是先遇到所有问题,然后下一波公司开始遇到这些问题时,就会看看我们做了什么。其实在 Google,内部是 Blaze,外部是 Bazel,所以我们一直有开源的传统。这也有助于招聘,或者展示:“嘿,如果你想在这一领域处于领先地位,并且想一直做这件事,而不是偶尔贡献一下,这就是我们所做的。”

瑞安:

这个开源的决定,是工程师自下而上推动的,还是领导层也参与了?比如说"这会很有价值",然后你们写了一份文档什么的?

博林:

我想两者都有。像 React 和 PyTorch 这样的成功案例,对公司的价值是毋庸置疑的。但还有一些项目,取决于经济环境,如果经理觉得工程师在开源上投入太多,他们会抱怨。所以这几乎总是自下而上的。虽然没有遇到太多阻力,但通常你会得到一两个好的会议演讲或不错的博客文章。那些博客文章随着时间的推移确实会带来红利,比如在招聘方面。它们的保质期比人们想象的要长。

晋升首席工程师(E8)后的挣扎

瑞安:

你晋升到了 E8,我猜你心里的期望值也提高了,现在你需要去寻找一个 E8 级别的问题。晋升后你做了什么?

博林:

我想那是我有点“用力过猛”的时候。我试图去帮助改善 Web 速度,因为 http://facebook.com 的加载时间确实很糟糕,架构有点陈旧。问题太大了,而我并没有相关经验。Facebook 那些做 Web 的人已经做了很久,而我一直专注于移动端和开发工具,我并不在那个世界里。我记得当时我们甚至开始尝试从源码编译 V8,试图改变我们生成 JavaScript 的方式,看看是否对 V8 更友好。我们只是在盲目尝试,结果什么都没成功。我觉得不同的人适合不同的项目,那显然不是适合我的项目。我更擅长从零开始写代码的项目,而那个项目更多是关于查看数据和与人沟通,那不是我的强项。

瑞安:

我记得你提到过,在职业生涯的那个阶段,你有一种"英雄之旅"的想法。那是什么意思?

博林:

这有点尴尬,因为这涉及自我意识。这种想法是:“这里有一个戈耳狄俄斯之结(难题),所有工程师都在说‘要是有人能进来解决这个工程问题就好了’。”我当时想:“我懂 JavaScript,我可以进来解决它。”但我没做到。这是一个重要的教训,我至少又重学了一次:我可以做很多事情,但只有一小部分是我真正喜欢且能取得成功的。如果我坚持做那些我真正喜欢的事情,我会成功得多。我尝试随着时间推移去扩展这个范围,但我们不必成为所有事情的专家。接受这一点,并拥抱它。

为 Facebook 构建虚拟文件系统

瑞安:
那么在那之后,你是如何发现 E8 职级所面临的规模化问题的?接下来的日子是怎么样的?

博林:
我想那也有点运气的成分。我们当时会定期举行一些小型工程师峰会,头脑风暴一下未来可能会遇到的瓶颈。我当时提到,随着代码仓库(repo)不断增长,迟早会遇到规模化问题。后来成为我经理的布莱恩·奥沙利文(Brian O'Sullivan)决定召集一些人手,着手开发一个虚拟文件系统(virtual file system),试图提前解决这个问题。于是,我和亚当·辛普金斯(Adam Simpkins)、韦斯·弗朗(Wes Furlong)组成了团队,他们都是非常出色的工程师,实际上在项目初期,我一度觉得自己是团队里最差的那个。

瑞安:
你刚才提到了虚拟文件系统,从宏观层面来看,对于像 Meta 这样的公司,拥有这样的系统有什么好处?

博林:
如果你认同单一代码仓库(monorepo)的理念,即把所有代码放在一个仓库里,那么人们在任何时候通常只需要用到其中一小部分文件。虚拟文件系统的设计初衷是让所有工具都围绕它构建。这样当你克隆仓库、切换到不同的提交(commit)或进行类似操作时,不需要在磁盘上真正写出仓库里的每一个文件。

这在传统文件系统中是默认行为,但它会随着仓库大小的增加而线性增长,最终你会感到非常痛苦。这个系统其实包含两个部分:第一是构建这个虚拟文件系统,它能识别用户当前处于哪个提交版本。如果操作系统向我索要某个文件的内容,我可以随时去获取,并让它看起来就像所有文件都已经预先加载好了一样。

另一部分,也是我可能更擅长的部分,是预判工具链中那些习惯于读取所有文件的工具。你知道,像 ripgrep 这种工具,它会扫描所有内容。我们需要改变开发流程和工具的设计,让它们考虑到虚拟文件系统的存在。因为如果你现在还用老办法把所有文件都实体化(materialize),那你之前所做的所有优化努力就都白费了。

瑞安:
所以从宏观上看,它本质上就是对庞大文件系统的懒加载(lazy loading),因为不需要在开始时处理所有东西,所以效率更高。

博林:
是的。

瑞安:
你刚才说你更擅长的那部分,就是将所有东西集成到这个基础之上?

博林:
对。我和汉森·王(Hanson Wang)——他现在也和我一起在 Codex 团队——做过一件事。传统的 IDE 或编辑器想要实现极速文件搜索,通常第一步就是遍历整个文件系统来确定有哪些文件。

我当时想,这会是个大问题,会抵消掉我们所有的优化成果。于是我们开始思考:如何实现一种不会破坏性能的文件搜索?后来我们构建了一个名为 "Myles"(My Files 的缩写)的文件系统。它通过定时任务(cron job)索引并摄取主干(trunk)上的所有新提交,只追踪文件的增删情况,不需要读取内容,因为只需要文件名。汉森想出了一些巧妙的方法来维护索引,从而支持模糊匹配。这样不仅是子字符串匹配,即使你拼写错误,或者只想输入驼峰命名法中的大写字母,也能搜到。

他设计了一种非常有趣的方式来表示所有出现过的文件,并用位图(bits)来标记在特定提交版本中该文件是否存在。当你发送查询请求时,带上你当前的提交版本以及本地的增删改动,我们就能在 10 到 20 毫秒内从上百万个文件中检索出结果。这比 XcodeVS Code 原生提供的搜索要快得多。

最初这个虚拟文件系统叫 Eden。但因为 Myles 实在太快了,而且作为内部的 Thrift 服务开放,人们开始把它用在各种地方。我离开时,全球至少有 30 台服务器在运行 Myles,显然它的用途远不止个人搜索文件那么简单。

瑞安:
你提到的实现细节让我想到了算法题。这听起来像是一种树状结构,比如字典树(trie)?

博林:
有趣的是,我们用了两个并行数组。一个是文件内容,另一个是指向索引的整数。我们还用了一个 64 位的掩码(mask),涵盖了 26 个小写字母、26 个大写字母、10 个数字以及连字符等。如果搜索的文件中包含某个字符,对应的位就会被置位。

这样我们就能先快速过滤掉大量无关项。而且这些数组是并行设计的,对 CPU 的缓存非常友好,能够线性读取内存,也非常适合并行计算。

延迟的杰出工程师(E9)晋升与经验教训

瑞安:
我了解到你做过 Eden 和 Myles,这些项目最终促成了你的晋升。但在那之前,你在影响力(influence)和冲突处理方面似乎学到了一些东西?

博林:
是的。作为一名主要写代码的 E8,这确实是个挑战。在这个职级或更高职级的人中,大多数人其实已经不怎么写代码了,他们更多是在跨团队协作、撰写大型文档并争取各方支持。

作为 E8,如果只靠写代码很难达到预期的影响力。我意识到我需要花时间去影响他人,这对我、对我的经理都有好处。但我当时对自己的见解过于自信,导致我表现得过于强硬,结果适得其反。我的晋升被推迟了,因为当时微软收购了 GitHub,我非常焦虑,因为 Nuclide 主要基于 GitHub 的技术构建,我担心它会被 VS Code 取代——事实证明我是对的,确实发生了。

我当时太焦虑了,一直在催促团队,却忽略了大家对现状很满意,并不想改变。结果我被找去谈话了,晋升也被搁置。后来我甚至接受了专门的辅导来改善这一点。

瑞安:
你从辅导中学到的最重要的一点是什么?

博林:
对我来说,是学会识别那些会让我产生应激反应的触发点。当意识到自己情绪激动时,我会选择先冷静下来,或者如果我觉得自己无法进行建设性的对话,我会选择去和对方的经理沟通,而不是像“闯进瓷器店的公牛”一样直接冲向工程师。

瑞安:
这很有趣,因为事后看来你是对的,你是在为正确的事情而战,但却被要求“冷静一点”。当事情真的按你预想的发展时,你是什么心情?

博林:
大约一年后,我和相关人员进行了一些沟通,我说:“嘿,我们能把账算平吗?”毕竟当时因为这件事我受了不小的打击。最后我们达成了和解。

瑞安:
所以教训在于处理方式,而不在于你的判断本身?

博林:
是的,确实如此。

加入 OpenAI

瑞安:
你在 Meta 过得很愉快,最终还是离开了。是什么吸引你来到 OpenAI?

博林:
原因有很多。我在 2023 年底面试了 OpenAI。在 Meta 时,我一直在尝试做基于大语言模型(LLM)的开发工具,比如我们内部的 "Code Compose"。当时大家对快速交付和推动技术边界充满热情,但我也经常听到反馈:“为什么这不如 GPT-4?”我只能解释说我们用的是 Llama 2,不是同一个东西。我不是研究人员,但我渴望构建产品,我想去一个能使用最强模型的地方。

其次,这里聚集了我非常尊敬的人,我希望能和这些资深人才共事。第三,OpenAI 处于一个非常特殊的时期,感觉就像 2000 年的 Google,已经站稳了脚跟并找到了产品市场契合点(product-market fit)。最后,我一直想做消费级产品,虽然在 Facebook 做了开发者工具,但用户群只有两万名同事。现在在 Codex 团队,用户量级已经达到百万级,而且还在呈垂直增长,这种影响力是完全不同的。

研究驱动与工程驱动的文化

瑞安:
Meta 是典型的工程驱动,工程师是核心。而像 OpenAI 这样的实验室公司,研究往往是第一优先级的。作为一名工程师,你如何看待这种研究驱动与工程驱动的文化差异?

博林:
这确实需要适应。如果你来自大厂,肯定会有这种感觉。虽然我们非常看重影响力,但如果模型本身不够好,我们在 harness(Codex 的配套工具)上做再多工作也没用。所以我很庆幸我们与研究团队紧密相邻,能够共同开发产品。这种“与模型构建者一起构建产品”的体验,正是我离开 Meta 的原因之一。

Codex 背后的故事

瑞安:
你提到刚到这里就开始做 Codex。我听说 Codex CLI 的初期发布反响并不如预期,但后来却成功了,能讲讲这段故事吗?

博林:
那是一段疯狂的旅程。Codex CLI 是在 2025 年 4 月发布的,当时作为 o4-mini 发布直播结尾的”彩蛋”。我们进行了现场演示并开源了它,反响很热烈,两周内就收获了上万颗星。但它发布得过于仓促,我们当时的人手不足以支撑后续的维护。

一个月后,团队又推出了 Codex Web,这是一个资源更充足的项目。虽然长期愿景是正确的,但当时用户更倾向于本地编码 agent。到了夏天,我们意识到本地 agent 依然有更强的产品市场契合度,但我也坚信,从长远看,agent 需要云端算力。于是我们调整了重心,增加了 Codex CLI 的人手,并开始开发 VS Code 插件。

8 月份非常疯狂,GPT-5 发布了,我们更新了终端 UI,支持了开源模型,还发布了 VS Code 插件。这些因素的汇聚形成了转折点,带来了现在的垂直增长。

瑞安:
你为什么如此坚信云端才是长期的方向?

博林:
想象一下,如果你想让 agent 自动处理每一个 GitHub issue 或任务,你不能全靠笔记本电脑。虽然作为个人开发者,我可能依然喜欢本地 agent,但从行业角度看,agent 的算力必然会向云端迁移。

他是如何使用 Codex 的

瑞安:
Codex 的使用量增长了 5 倍,用户超过百万。你的 AI 工作流有什么变化吗?

博林:
我现在比预想中更依赖它。对于 Codex 本身的代码,我依然会仔细审查,因为这影响到所有人。但对于一些一次性的原型项目,我甚至完全不看代码,这非常自由。现在我更倾向于在 Codex 应用中进行多任务处理,因为在一个窗口里就能搞定一切。有时候我会觉得,如果我能更高效地向模型提问,我的产出还能翻倍。

瑞安:
你现在写的代码中,人类编写和模型生成的比例大概是多少?

博林:
应该是 80% 到 90% 由模型生成。特别是在调试测试或处理 CI 问题时,这简直是解放了生产力。

瑞安:
哪些问题适合 LLM,哪些不适合?那 10% 到 20% 你必须亲自动手的部分是什么?

博林:
Codex 的 harness 部分是用 Rust 编写的,涉及很多操作系统底层的操作,尤其是沙箱(sandboxing)部分。为了确保安全完整性,我必须亲手把关。我会先搭建好基础框架,确保核心逻辑正确,剩下的部分再交给模型去填充。此外,现在我也会让模型帮我把过大的 PR 拆分成可审查的小块,这节省了大量时间。

瑞安:
代码审查呢?大家是手动审查,还是有 agent 辅助?

博林:
我们依然会进行人工最终审查。不过现在大家开始用 AI 来撰写 PR 总结,这让审查效率大幅提升,因为总结里包含了 PR 的“为什么”和“是什么”。这确实让审查过程顺畅了很多。

为什么 Codex 的 harness 是开源的

瑞安:

我想聊聊 Codex CLI。它是开源的,为什么要把它开源呢?

博林:

对于这种对你本地机器运行至关重要的东西,开源是其中的一个考量。我本人对这类事情算不上最狂热的拥护者,但我很理解这种心态。毕竟,你要把这个东西装在我的机器上,我肯定关心它在做什么。我认为在 AI 领域,人们能查看代码并了解其运作机制尤为重要,因为大家对 AI agent(智能体)这类东西有很多疑问。

所以我觉得在这个领域,开源真的很关键。此外,我们也确实收到了许多很棒的贡献和错误报告,如果闭源的话,我们可能会错过这些反馈。再者,这也是一种与世界分享“事情是如何完成的”方式。我们是通过代码来做这件事的,对吧?我之前写过一篇关于 Agent Loop(智能体循环)如何工作的博客文章。

我们确实计划分享更多内容,我本人也很期待,只是时间有限,这是个制约因素。说起来很有趣,之前有两位候选人来面试,其中一个说:“嘿,这代码是我写的,对吧?”我说:“不,不,是我写的。”另一个人进来后说:“哦,看得出来,这代码确实不是外包出去写的。”我说:“太好了,谢谢!”

瑞安:

你提到了那篇博客。Codex 是如何发现其环境中可用资源的?我在运行这些工具时,觉得它真的很神奇,它会自己思考,并在我的终端里发现各种东西。这通常是怎么运作的?

博林:

是的,这有几种情况。首先,Codex 的基础训练中显然包含了一些知识,比如它非常喜欢用 ripgrep,而且用得很好,能以此找到各种东西。另外,如果你有自己的 agent.md 文件,并在里面写明“在这个仓库里,这些工具非常重要,你应该使用它们”,或者通过 README 等文件说明,它也能获取信息。

当然,如果你使用了 MCP,并将这些 MCP 服务器与你的工作环境关联起来,它会在对话开始时注入一组工具定义。所以,这甚至都不算是 Codex 的“发现”过程,而是直接把工具摆在它面前。我明白了。

瑞安:

所以一部分是 harness(工具框架)明确地将其放入上下文,但很大一部分工作还是由模型自己完成的,对吗?

博林:

是的。

顶级技术书籍推荐

瑞安:

回顾你的职业生涯,你工作的广度和深度令人惊叹。从 JavaScript 前端,到各种开发工具、构建系统、模糊文件搜索、虚拟文件系统,现在又在做 Codex。我相信你一定在不断学习以攻克这些项目。有哪些顶级技术书籍对你的自我提升帮助最大?

博林:

嗯,有一本关于操作系统的书,大概有一千页左右,是 Addison-Wesley 出版的。我记不清作者名字了。有趣的是,当时我在做虚拟文件系统项目,在那之前,我的职业生涯里甚至从没写过 C 语言,本科时学的也比较理论化,从没真正接触过底层。

结果我竟然在做一个虚拟文件系统项目,这非常底层。所以我当时开玩笑说,我是那个项目里最差劲的工程师。有一次别人聊到某个概念,我发现自己完全听不懂,觉得很尴尬。我就问:“我该读什么书?”当时的经理亚伦·库什纳(Aaron Kushner)说:“有一本一千页的书。”

我说:“好,买了。”我把它从头到尾读了一遍,走到哪带到哪,直到读完。很多人在软件工程领域走了很远,却对计算机底层运作一无所知,这既神奇又有点悲哀或奇怪。软件工程中存在太多抽象层了,一方面这让人感到自由,但另一方面也确实有点疯狂。

我想对大家说的是,要主动尝试深入理解这些层级。我之所以能解决一些别人解决不了的问题,就是因为我发现两个层级之间存在冗余,如果能去掉它,就能获得 10 倍的性能提升。如果你只在很高的层面操作,就不知道哪里可以拆解。

书籍方面,我很喜欢 O'Reilly 出版的 Rust 系列书籍,我是 Rust 的忠实粉丝,而且这些书写得非常透彻。另外,我还建议大家去参加 CTF(夺旗赛),这是一种安全竞赛。它能帮你培养对抗性思维,就像一场“计算机十项全能”。

比赛中会有各种挑战,有的需要你懂汇编,有的需要你分析别人写得烂糟糟的 PHP 管理页面。它强迫你拓宽知识面,这是其他方式很难做到的。而且它像游戏一样,非常有趣。

瑞安:

你能简单介绍一下什么是 CTF 吗?

博林:

它可以有很多种形式,但通常是在信息安全领域。有一种“危险边缘(Jeopardy)”风格的比赛,会预先设计好一系列挑战,每个挑战都有分值。在固定时间内,个人或团队尝试解决这些问题。

比赛中有一个“旗帜(flag)”,其实就是一段秘密文本。如果你能发现它,就证明你通过逆向工程或其它手段解决了挑战。你提交这段文本作为凭证。这就像一场竞赛,看谁先解决所有问题,或者在规定时间内得分最高。

瑞安:

所以这就像是终端里的密室逃脱,你只能用计算机来解决一切?

博林:

是的。

瑞安:

明白。所以你的建议是,想成为更好的工程师,就应该去参加这些 CTF,因为它们强迫你解决那些能让你变强的问题。

博林:

是的。比如你每天只写 React,可能永远不会打开 GDB 去逆向一个井字棋游戏。但我为了 CTF 挑战做了这件事,学会了如何使用 GDB。当你以后遇到其他问题时,你的工具箱就比别人丰富多了。

为什么深厚的技术功底依然有价值(至少目前如此)

瑞安:

很多人,尤其是职业生涯早期的人,看到 Codex 在终端里帮他们搞定一切,就会想:“我不需要学 GDB 了,因为 Codex 会。”面对这些 AI 工具,你对工程师的教育有什么建议?

博林:

每个人都在努力回答这个问题。我个人还是坚持认为,强迫自己穿透抽象层、深入理解底层运作机制非常重要。

我相信未来会改变,但目前,你向 agent 提出的问题质量,直接决定了你得到的结果质量。如果你问不出正确的问题,可能就得不到最好的工程方案。随着技术发展,也许这一层也会被抹平,但我不知道具体时间表。事情发生得比我们预想的要快。但总的来说,学会如何提出正确的问题至关重要。我自己的直觉和品味也是通过多年经验积累出来的,对于刚起步的人,我还没完全想好这意味着什么。

瑞安:

回顾你的职业生涯,在高水平岗位上的期望值高得惊人。对大多数人来说,E7 或高级 Staff 级别已经是难以企及的影响力高度了。而你又往上走了两级。在日常工作中,你如何看待这些疯狂的期望?这会让你感到压力吗?

博林:

我觉得压力一直都在。因为我参与过绩效评定(calibration),讨论别人的级别和影响力时,你必须非常公正。当你意识到别人也在评定你时,这确实有点吓人。当你达到 E8 级别,相当于总监(Director)时,你会想:“我该如何产生与管理百人团队的总监同等的影响力?”

很多高级个人贡献者(IC)是通过不同的人员管理方式来实现的,比如撰写文档、协调团队。他们之所以不是总监,是因为他们拥有技术公信力,当他们与团队沟通时,效果与工程总监完全不同。

即使在开始一个项目时,我也不会只选“好玩”的项目。我会思考:我个人写哪些代码能最大化影响力?如果别人能做到 80% 的效果,我可能就会让别人去做。即便如此,领导一个五人项目要达到 E8、E9 的影响力依然很难。你需要找到那些能产生“乘数效应”的项目,比如虚拟文件系统,它解锁了后续无数的可能性。

另外,高级经理的作用也很关键,他们能把高级 IC 和合适的项目匹配起来。有些工程师是顶级的“修复者”或“编码者”,但他们不一定能提出新点子,这种时候就需要经理来慧眼识珠。

如何开启项目

瑞安:

你的老同事亚当·恩斯特(Adam Ernst)提到过你,他特别称赞你开启项目的能力。你很多项目都是凭空创造的,有了想法就去写原型,然后回来证明这是更好的方案。对于那些想从零开始构建项目的工程师,你有什么建议?

博林:

很多好项目都源于对现状的不满。有趣的是,有时我为了赶进度,甚至没想过最好的实现方式是什么。举个例子,很久以前在做 Google Calendar 时,我想要在日历里显示天气图标。我那时主要写 JavaScript,没做过后端,就硬着头皮把东西拼凑起来了。

结果我的技术负责人问:“你存这些天气数据用的是什么格式?”我说:“我直接扔了一堆 XML。”他当时就说:“我们应该用 Protocol Buffers。”我当时满脑子都是天气图标,根本没想过问问别人有没有更好的方法。

瑞安:

所以你独特的技能在于挖掘不满并解决自己的问题。

博林:

是的。

瑞安:

很多人在开发环境中看到构建速度很慢,只会去休息室喝杯咖啡。是什么给了你信心,让你觉得你能做得更好?

博林:

这得归功于我在 Google 的经历。虽然我没在 Blaze 团队工作过,但我知道有那种架构的存在,而且它比现有的好得多。这就是“存在性证明”。至于我能不能做出来,那是另一回事。我通常把自己定位为一台“编码机器”。我总有信心快速构建原型,至少能验证我的基本假设。只要你足够坚定,总能找到办法。

关于写作和职业规划的建议

瑞安:

很多去大公司的人,看到世界级的架构后,会去构建它的新版本。我看过很多你的文章,非常清晰,是技术写作的典范。你对想提升写作能力的工程师有什么建议?

博林:

多读好的文章是起点,潜移默化中你会学到模式。最重要的是思考:我到底想传达什么?读者真正想知道什么?提前列好大纲非常重要。问问自己:从这一点到那一点,跨度是否太大?是否漏掉了什么关键信息?如果你能预判读者的困惑,并适时补充他们需要的例子,这对技术写作来说至关重要。

瑞安:

你有一篇关于职业生涯的笔记,里面提出了一个三步走的影响力计划,能解释一下吗?

博林:

第一步:找出你真正喜欢做的事。第二步:找出对雇主来说真正不可或缺的事。第三步:找到两者的交集,然后全力投入。如果你能做到这一点,通常会非常成功。如果找不到交集,也许就该换个地方了。

给年轻时的自己的建议

瑞安:

最后一个问题,如果回到职业生涯初期,你会给自己什么建议?

博林:

我应该更早地保持开放心态,学习更多东西。人们往往会对第一门编程语言产生感情,甚至为它辩护,因为它是你进入编程世界的敲门砖。但这也是个陷阱,因为你一旦掌握了它,就不想再离开舒适区去学习新东西了。

我在 JavaScript 上投入了太多时间,直到很久以后才开始写 C。如果我当时能更灵活、更愿意尝试不同类型的项目,也许职业生涯会有更早的突破。

瑞安:

也许未来有了 Codex,人们就不再有这种障碍了。你可以直接说:“我懂 JavaScript,帮我用 Rust 重写这个。”

博林:

确实,这会打开很多大门。

瑞安:

非常感谢你的时间!

博林:

谢谢你,瑞安。